package org.drl.tvkit.dao;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.drl.tvkit.KitApplication;
import org.drl.tvkit.dao.ApplicationTable.AppInfoProto;
import org.drl.tvkit.util.FormatUtils;
import org.drl.tvkit.util.L;
import org.drl.tvkit.util.StringUtil;

import android.content.ContentValues;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.Drawable;
import android.provider.BaseColumns;

public class ShortTable extends AbstractTable {


	/*
	 * 字段 _ID 索引 DATA_TEXT 应用名称 DATA_ICON 应用图标 DATA_PNAME activity包名
	 * DATA_CNAME activity类名
	 */
	public static final class Fields implements BaseColumns {
		public static final String TAB_NAME = "ShortTable";

		public static final String DATA_TEXT = "_DATA_TEXT";
		public static final String DATA_ICON = "_DATA_ICOM";
		public static final String DATA_PNAME = "_DATA_PNAME";
		public static final String DATA_CNAME = "_DATA_CNAME";

		public static final String COLUMNS[] = { _ID, DATA_TEXT,
				DATA_ICON, DATA_PNAME, DATA_CNAME };
	}

	static int getId(Cursor cursor) {
		return cursor.getInt(cursor.getColumnIndex(Fields._ID));
	}

	static String getText(Cursor cursor) {
		return cursor.getString(cursor.getColumnIndex(Fields.DATA_TEXT));
	}

	static String getIcon(Cursor cursor) {
		return cursor.getString(cursor.getColumnIndex(Fields.DATA_ICON));
	}

	static String getPName(Cursor cursor) {
		return cursor.getString(cursor.getColumnIndex(Fields.DATA_PNAME));
	}

	static String getCName(Cursor cursor) {
		return cursor.getString(cursor.getColumnIndex(Fields.DATA_CNAME));
	}
	private static ShortTable instance;

	public static ShortTable getInstance() {
		if (instance == null) {
			instance = new ShortTable();
		}
		return instance;
	}

	private int mCount;
	private String mIconFilePath;
	private String TAG = "ShortTable";
	private boolean flag;
	private ShortTable() {
		File iconFile = new File(KitApplication.getInstance().getFilesDir()
				+ File.separator + "icons");
		if (!iconFile.exists()) {
			iconFile.mkdir();
		}
		mIconFilePath = iconFile.toString();
	}

	public final int getCount() {
		if(!flag){
			SQLiteDatabase db = DataBaseManager.getInstance().getReadableDatabase();
			updateCount(db);
		}
		return mCount;
	}



	@Override
	public void create(SQLiteDatabase db) {
		String sql;
		sql = "CREATE TABLE " + Fields.TAB_NAME + " (" + Fields._ID
				+ " INTEGER PRIMARY KEY,"
				+ Fields.DATA_TEXT + " TEXT," + Fields.DATA_ICON + " TEXT,"
				+ Fields.DATA_PNAME + " TEXT," + Fields.DATA_CNAME + " TEXT);";
		DataBaseManager.execSQL(db, sql);
	}

	

	public List<AppInfoProto> readAllList() {
		List<AppInfoProto> mRm = new ArrayList<AppInfoProto>();
		Cursor c = list();
		
		while (c.moveToNext()) {
			String $text = getText(c);
			String $icon = getIcon(c);
			String $pname = getPName(c);
			String $cname = getCName(c);
			int $id = getId(c);
			AppInfoProto $apv = new AppInfoProto();
			$apv.setText($text);
			$apv.setIcon($icon);
			$apv.setPname($pname);
			$apv.setCname($cname);
			$apv.setId($id);
			mRm.add($apv);
		}
		closeCurosr(c);
		return mRm;
	}
	public Map<String,AppInfoProto> readAllMap() {
		Map<String,AppInfoProto> mRm = new HashMap<String,AppInfoProto>();
		Cursor c = list();
		
		while (c.moveToNext()) {
			String $text = getText(c);
			String $icon = getIcon(c);
			String $pname = getPName(c);
			String $cname = getCName(c);
			int $id = getId(c);
			AppInfoProto $apv = new AppInfoProto();
			$apv.setText($text);
			$apv.setIcon($icon);
			$apv.setPname($pname);
			$apv.setCname($cname);
			$apv.setId($id);
			mRm.put($pname, $apv);
		}
		closeCurosr(c);
		return mRm;
	}

	public List<AppInfoProto> readAllList(int MAX_COUNT, AppInfoProto mfrist) {
		List<AppInfoProto> mRm = new ArrayList<AppInfoProto>();
		mRm.add(0, mfrist);
		Cursor c = list();
		int i = 1;
		while (c.moveToNext()) {
			if(i == MAX_COUNT){
				break;
			}
			String $text = getText(c);
			String $icon = getIcon(c);
			String $pname = getPName(c);
			String $cname = getCName(c);
			AppInfoProto $apv = new AppInfoProto();
			$apv.setText($text);
			$apv.setIcon($icon);
			$apv.setPname($pname);
			$apv.setCname($cname);
			mRm.add(i,$apv);
			i++;
		}
		closeCurosr(c);
		return mRm;
	}

	@Override
	protected String getTableName() {
		return Fields.TAB_NAME;
	}

	@Override
	protected String[] getProjection() {
		return Fields.COLUMNS;
	}

	

	public AppInfoProto readAppInfo(String packageName,int i){
		AppInfoProto $app = new AppInfoProto();
		final PackageManager pm = KitApplication.getInstance().getPackageManager();
		ApplicationInfo appInfo = null;
		try {
			appInfo = pm.getApplicationInfo(packageName, 0);
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		String name = (String) appInfo.loadLabel(pm);
		Drawable icon = appInfo.loadIcon(pm);
		String className = appInfo.name;
		$app.setText(name);
		$app.setIcon(saveDrawableIcon(icon, "appicon_add"+i+".png"));
		$app.setPname(packageName);
		$app.setCname(className);
		return $app;
	};
	
	public final void writes(List<AppInfoProto> _data) {
		if(_data.size() > 0){
			insertList(_data);
		}else{
			L.e(TAG, "数据插入失败");
		}
	}
	
	String saveDrawableIcon(Drawable icon, String pkgName) {

		File file = new File(mIconFilePath, pkgName);
		if(file.exists()){
			return file.toString();
		}
		byte[] bytes = FormatUtils.getInstance().Drawable2Bytes(icon);
		try {
			FileOutputStream fio = new FileOutputStream(file);
			if(bytes.length > -1){
				fio.write(bytes);
				fio.flush();
				fio.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return file.toString();
	}
	int i = 0;
	public void insertItem(String packageName) {
		AppInfoProto _item = readAppInfo(packageName, i++);
		SQLiteDatabase db = DataBaseManager.getInstance().getWritableDatabase();
		ContentValues cv = new ContentValues();
		cv.put(Fields.DATA_TEXT, _item.getText());
		cv.put(Fields.DATA_ICON, _item.getIcon());
		cv.put(Fields.DATA_PNAME, _item.getPname());
		cv.put(Fields.DATA_CNAME, _item.getCname());
		db.insert(getTableName(), null, cv);
		updateCount(db);
	}
	
	public void deleteItem(AppInfoProto _item){
		SQLiteDatabase db = DataBaseManager.getInstance().getWritableDatabase();
		db.delete(getTableName(),  Fields._ID+"= ?", new String[]{String.valueOf(_item.getId())});
		updateCount(db);
	}
	public void deleteItem(String pname){
		final SQLiteDatabase db = DataBaseManager.getInstance()
				.getWritableDatabase();
		File _delFile = null;
		Cursor result = db.query(getTableName(), getProjection(),
				Fields.DATA_PNAME + "= ?", new String[] { pname }, null, null,null);
		if (result.moveToNext()) {
			String path = getIcon(result);
			if (StringUtil.isNotNull(path)) {
				_delFile = new File(path);
			}
		}
		closeCurosr(result);
		db.delete(getTableName(), Fields.DATA_PNAME + "= ?",new String[] { pname });
		updateCount(db);
		final File _file = _delFile;
		Runnable run = new Runnable() {
			@Override
			public void run() {
				if(_file!=null){
					if(_file.exists()){
						_file.delete();
					}
				}
			}
		};
		KitApplication.getInstance().runBackground(run);
	}

	void insertList(List<AppInfoProto> _list) {
		final SQLiteDatabase db = DataBaseManager.getInstance().getWritableDatabase();
		L.e(TAG, "insertList-->size-->"+_list.size());
		db.beginTransaction();
		for (AppInfoProto _item : _list) {
			ContentValues cv = new ContentValues();
			cv.put(Fields.DATA_TEXT, _item.getText());
			cv.put(Fields.DATA_ICON, _item.getIcon());
			cv.put(Fields.DATA_PNAME, _item.getPname());
			cv.put(Fields.DATA_CNAME, _item.getCname());
			db.insert(getTableName(), null, cv);
		}
		db.setTransactionSuccessful();
		db.endTransaction();
		updateCount(db);
	}
	void updateCount(SQLiteDatabase db) {
		Cursor c = db.query(getTableName(), getProjection(), null, null, null,
				null, null);
		if (hasData(c)) {
			mCount = c.getCount();
		}
		closeCurosr(c);
	}
	
}
